package com.calmcar.adas;

import android.app.Activity;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.graphics.Color;
import android.hardware.Camera;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.ToggleButton;

import com.calmcar.adas.apiserver.AdasConf;
import com.calmcar.adas.apiserver.AdasServer;
import com.calmcar.adas.apiserver.model.CdwDetectInfo;
import com.calmcar.adas.apiserver.model.FrontCarInfo;
import com.calmcar.adas.apiserver.model.LdwDetectInfo;
import com.calmcar.adas.apiserver.out.ActiveSuccessListener;
import com.calmcar.adas.apiserver.out.CvCameraViewFrame;
import com.calmcar.adas.apiserver.out.DetectInitSuccessListener;
import com.calmcar.adas.apiserver.out.WarnSpeakManager;
import com.calmcar.adas.apiserver.view.AdasDrawView;
import com.calmcar.adas.gps.LocationTickListener;

import org.opencv.core.Mat;

import java.text.DecimalFormat;

/**
 * Created by 高立帅 on 2018/2/1.
 */

public class MainActivity extends Activity  implements CameraBridgeViewBase.CvCameraViewListener2 ,AdasServer.CameraDataProcessCallBack,CompoundButton.OnCheckedChangeListener, View.OnClickListener {
    private static final String TAG = "MainActivity";
    private CameraBridgeViewBase mOpenCvCameraView;
    private CameraDataProcess cameraDataProcess;
    private WarnSpeakManager warnSpeakerManager;
    //校准
    private Button btn_check_line;
    private LinearLayout ln_up_down,ln_left_right;
    private View v_up_down,v_left_right;
    private Button btn_set_line_ok;
    private int lastX,lastY;
    private int desLastX,desLastY;
    private int deadStartX;
    private int deadEndX;
    private RelativeLayout center_conf_rela;
//    float mScale=0;
    private int deadStartY;
    private int deadEndY;

    @Override
    public void onBackPressed() {
        super.onBackPressed();
        finish();
    }

    //底部菜单相关
    private int mVisiable=View.GONE;

    @Override
    public void onProcessBack(LdwDetectInfo ldwDetectInfo, CdwDetectInfo cdwDetectInfo) {
        checkAdasWarnInfo(ldwDetectInfo,cdwDetectInfo);
        adasDrawView.drawBitmap(ldwDetectInfo,cdwDetectInfo);
    }

    private LinearLayout mBottomContainer;
    //车道线是否检测成功信号
    private boolean lane_detect_sign=false;
    //    private double mRate;
    //GPS相关
    private TextView tvMapInfo;
    private Context mContext;
    //行驶车速_line_tmp;
//    private SharedPreferences spf=null;
    private ToggleButton car_btn_detect,line_btn_detect;
    private Button btn_set,btn_check;
    private TextView adasToggle;
//    private Function function;

    private AdasServer adasServer;
    AdasDrawView adasDrawView;

    private TextView adjInfo ;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        requestWindowFeature(Window.FEATURE_NO_TITLE);//隐藏标题
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(R.layout.activity_main);
        mContext = this;
        adasServer=new AdasServer(mContext);
        warnSpeakerManager = new WarnSpeakManager(mContext);
        initView();
    }
    @Override
    public void onResume()
    {
        super.onResume();
        if(getRequestedOrientation()!= ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE){
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
        }
    }

    public void onDestroy(){
        super.onDestroy();
        try{
            adasServer.serverStop();
            warnSpeakerManager.stop();
            cameraDataProcess.releaseCamera();
        }catch (Exception e){}
        System.exit(0);
    }

    private void initView() {
        mOpenCvCameraView= findViewById(R.id.javaCameraView);
        adasDrawView=findViewById(R.id.adasDrawView);
        mOpenCvCameraView.setFrameSize(960,540);//960*540
        mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE);
        mOpenCvCameraView.setCvCameraViewListener(this);
        mOpenCvCameraView.setOnClickListener(this);
        mOpenCvCameraView.setMaxFrameSize(960,540);//864*480
        mOpenCvCameraView.enableFpsMeter();
        adasServer.setDetectInitSuccessListener(new DetectInitSuccessListener() {
            @Override
            public void onInitSuccess() {
                mOpenCvCameraView.enableView();
            }
        });
        adasServer.setActiveSuccessListener(new ActiveSuccessListener() {
            @Override
            public void onActiveCallBack(String type ) {
                String  type0=type+"";
                //type :1 首次激活成功  10 已经激活  2  未经授权，激活失败 3  网络错误，激活失败
            }
        });


        adasServer.setCameraDataProcessCallBack(this);
        adasServer.initConf(960,540);
        //设置室内测试模式
        adasServer.setAdasServerRunMode(0);

        warnSpeakerManager.initVideoPlayers(R.raw.car_out_line, R.raw.front_car_warn_level_one
                , R.raw.front_car_warn_level_two, R.raw.front_car_launch
        );

        adasServer.startServer( locationTickListener);

        mBottomContainer =findViewById(R.id.bottom_container);
        mBottomContainer.setOnClickListener(this);
        car_btn_detect = findViewById(R.id.car_detect);
        line_btn_detect = findViewById(R.id.line_detect);
        adasToggle = findViewById(R.id.adasToggle);

        btn_set = findViewById(R.id.btn_set);
        btn_set.setOnClickListener(this);

        btn_check= findViewById(R.id.id_btn_check_line);
        btn_check.setOnClickListener(this);


        car_btn_detect.setOnCheckedChangeListener(this);
        line_btn_detect.setOnCheckedChangeListener(this);
        //GPS
        tvMapInfo = findViewById(R.id.position_text_view);
        adjInfo = findViewById(R.id. adjInfo );
    }


    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        switch (buttonView.getId()) {
            case R.id.car_detect:
                adasServer.openDetect(isChecked,"car" );
                break;
            case R.id.line_detect:
                adasServer.openDetect(isChecked,"line" );
                break;
        }
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.javaCameraView:
                onClickMySelf();
                break;
            case R.id.id_btn_check_line:
                initNew(this);
                break;
            case R.id.id_btn_set_line_ok:
                float fcX=(desLastX)/mScaleWidth;
                float fcY=(desLastY)/mScaleHeight;
                adasServer.setVPPara((int)fcX,(int)fcY);
                center_conf_rela.setVisibility(View.GONE);
                break;
        }
    }

    private void onClickMySelf() {
        setVisible();
        setContainerVisible();
        if(mVisiable == View.GONE){
            setOutAnim();
        }else{
            setInAnim();
        }
    }
    private void setVisible(){
        mVisiable = mVisiable == View.GONE?View.VISIBLE:View.GONE;
    }
    private void setContainerVisible(){
        mBottomContainer.setVisibility(mVisiable);
    }
    private void setOutAnim(){
        mBottomContainer.setAnimation(AnimUtils.getBottomOutAnim(mContext));
    }

    private void setInAnim(){
        mBottomContainer.setAnimation(AnimUtils.getBottomInAnim(mContext));
    }

    private LocationTickListener locationTickListener =new LocationTickListener() {
        @Override
        public void onTickArrive(final  double longitude, final  double latitude ,final double rate  ) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    updateStateView(longitude, latitude , rate );
                }
            });

        }
    };

    public void updateStateView(double longitude,double latitude ,double rate ){
        DecimalFormat df1 = new DecimalFormat("######0.0");
        DecimalFormat df2 = new DecimalFormat("######0.00000");
        if(adasServer.isValidLocationState() ){
            tvMapInfo.setText("经度：" + df2.format( longitude) + "\n" + "纬度：" + df2.format( latitude)+ "\n"
                    + "速度：" + df1.format(rate)+"km/h");
            if (rate > 20){
                adasToggle.setVisibility(View.GONE);
            }else {
                adasToggle.setVisibility(View.VISIBLE);
            }
        }else {
            tvMapInfo.setText("GPS无信号"+ "\n");
        }
    }




    public  void checkAdasWarnInfo(LdwDetectInfo ldwDetectInfo, CdwDetectInfo cdwDetectInfo){
        if(ldwDetectInfo!=null){
            if(ldwDetectInfo.getLdwType()==2|| ldwDetectInfo.getLdwType()==3){
                warnSpeakerManager.carOutLine();
            }
        }
        if(cdwDetectInfo!=null){
            FrontCarInfo frontCarInfo=cdwDetectInfo.getFrontCarInfo();
            if(frontCarInfo!=null){
                switch (frontCarInfo.getFrontCarStateType()){
                    case 1:
                        warnSpeakerManager.frontCarSafeDistance();
                        break;
                    case 2:
                        warnSpeakerManager.frontCarCrash();
                        break;
                    case 3:
                        warnSpeakerManager.frontCarLaunchWarn();
                        break;
                }
            }
        }
    }



    @Override
    public void onCameraViewStarted(int width, int height) {}
    @Override
    public void onCameraViewStopped() {}

    @Override
    public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
        Mat mMat =inputFrame.rgba();
        //传送数据到检测服务
        adasServer.processDataAsyn(inputFrame);

        return mMat;
    }
    //手动校准
    float  mScaleWidth,mScaleHeight;
    private void initNew(Context context) {
        center_conf_rela=findViewById(R.id.center_conf_rela);
        btn_set_line_ok=findViewById(R.id.id_btn_set_line_ok);
        ln_up_down=findViewById(R.id.id_lin_up_down);
        ln_left_right=findViewById(R.id.id_lin_left_right);
        v_up_down = findViewById(R.id.id_view_up_down);
        v_left_right = findViewById(R.id.id_view_left_right);
        int width= mOpenCvCameraView.getMeasuredWidth();
        int height=mOpenCvCameraView.getMeasuredHeight();
//        if(AdasConf.IN_FRAME_HEIGHT>0){
//            mScale = Math.min(((float)height)/AdasConf.IN_FRAME_HEIGHT, ((float)width)/AdasConf.IN_FRAME_WIDTH);
//        }else{
//            mScale = 0;
//        }
        mScaleWidth=((float)width)/ AdasConf.IN_FRAME_WIDTH;
        mScaleHeight=((float)height)/ AdasConf.IN_FRAME_HEIGHT;

        float desWidth= AdasConf.IN_FRAME_WIDTH*mScaleWidth;
        float desHeight= AdasConf.IN_FRAME_HEIGHT*mScaleHeight;

        deadStartX= 150;
        deadEndX=(int)(desWidth-150);

        deadStartY=100;
        deadEndY=(int)(desHeight-100);

        RelativeLayout.LayoutParams relaParams =(RelativeLayout.LayoutParams) center_conf_rela.getLayoutParams(); //取控件textView当前的布局参数 linearParams.height = 20;// 控件的高强制设成20

        relaParams.width = (int)desWidth;// 控件的宽强制设成30
        relaParams.height = (int)desHeight;// 控件的宽强制设成30

        center_conf_rela.setLayoutParams( relaParams); //使设置好的布局参数应用到控件
        center_conf_rela.setVisibility(View.VISIBLE);
        int[] oldVPPara= adasServer.getVPPara();
        if(oldVPPara[0]>0){
            desLastX=(int)(oldVPPara[0]*mScaleWidth);
            desLastY=(int)(oldVPPara[1]*mScaleHeight);
            ViewGroup.MarginLayoutParams margin =new ViewGroup.MarginLayoutParams(ln_left_right.getLayoutParams());
            margin.setMargins(desLastX-margin.width/2, 0, (int)(desWidth-desLastX)-margin.width/2,0);
            RelativeLayout.LayoutParams layoutParams =new RelativeLayout.LayoutParams(margin);
            ln_left_right.setLayoutParams(layoutParams);

            ViewGroup.MarginLayoutParams margin1 =new ViewGroup.MarginLayoutParams(ln_up_down.getLayoutParams());
            margin1.setMargins(0, desLastY-margin1.height/2,0,  (int )(desHeight-desLastY)-margin1.height/2);
            RelativeLayout.LayoutParams layoutParams1 =new RelativeLayout.LayoutParams( margin1);
            ln_up_down.setLayoutParams(layoutParams1);

        }else{
            desLastX=(int)desWidth/2;
            desLastY=(int)desHeight/2;

            ViewGroup.MarginLayoutParams margin =new ViewGroup.MarginLayoutParams(ln_left_right.getLayoutParams());
            margin.setMargins((int)(desWidth/2)-margin.width/2, 0, ((int)(desWidth/2)-margin.width/2),0);
            RelativeLayout.LayoutParams layoutParams =new RelativeLayout.LayoutParams(margin);
            ln_left_right.setLayoutParams(layoutParams);
            ViewGroup.MarginLayoutParams margin1 =new ViewGroup.MarginLayoutParams(ln_up_down.getLayoutParams());
            margin1.setMargins(0, (int)(desHeight/2)-margin1.height/2,0,  (int)(desHeight/2)-margin1.height/2);
            RelativeLayout.LayoutParams layoutParams1 =new RelativeLayout.LayoutParams( margin1);
            ln_up_down.setLayoutParams(layoutParams1);
        }

        setGestureListener(context);//手势监听
        btn_set_line_ok.setOnClickListener(this);
        //计算平移距离
    }

    private void setGestureListener( Context context) {
        ln_left_right.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {

                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        v_left_right.setBackgroundColor(Color.parseColor("#0000FF"));
                        // 按下屏幕的操作
                        lastX=(int)event.getRawX();//获取触摸事件触摸位置的原始X坐标
                        break;
                    case MotionEvent.ACTION_MOVE:
                        // 在屏幕上移动的操作
                        int dx=(int)event.getRawX()-lastX;
                        int l=v.getLeft()+dx;
                        int b=v.getBottom();
                        int r=v.getRight()+dx;
                        int t=v.getTop();

                        if(l<deadStartX){
                            l=deadStartX;
                            r=deadStartX+v.getWidth();
                        }

                        if (r>deadEndX) {
                            r=deadEndX;
                            l=deadEndX-v.getWidth();
                        }

                        v.layout(l, t, r, b);
                        lastX=(int)event.getRawX();//获取触摸事件触摸位置的原始X坐标
                        desLastX=v.getLeft()+20;
                        v.postInvalidate();
//                        btn_set_line_ok.setVisibility(View.VISIBLE);
                        break;
                    case MotionEvent.ACTION_UP:
                        v_left_right.setBackgroundColor(Color.parseColor("#00FF00"));
                        lastX=(int)event.getRawX();//获取触摸事件触摸位置的原始X坐标
                        desLastX=v.getLeft()+20;
                        break;
                    case MotionEvent.ACTION_CANCEL:
                        // 手势撤消的操作
                        // 一般认为不能由用户主动触发。
                        // 系统在运行到一定程度下无法继续响应你的后续动作时会产生此事件
                        break;
                    default:
                        break;
                }
                // 这个返回值如果是false的话，那么它只会接受到第一个ACTION_DOWN的效果，
                // 后面的它认为没有触发，所以要想继续监听后续事件，需要返回值为true
                return true;
            }
        });

        ln_up_down.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {

                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        v_up_down.setBackgroundColor(Color.parseColor("#0000FF"));
                        // 按下屏幕的操作
                        lastY=(int)event.getRawY();
                        break;
                    case MotionEvent.ACTION_MOVE:
                        // 在屏幕上移动的操作
                        int dy=(int)event.getRawY()-lastY;
                        int l=v.getLeft();
                        int b=v.getBottom()+dy;
                        int r=v.getRight();
                        int t=v.getTop()+dy;

                        if (t<deadStartY) {
                            t=deadStartY;
                            b=deadStartY+v.getHeight();
                        }
                        if (b>deadEndY) {
                            b=deadEndY;
                            t=deadEndY-v.getHeight();
                        }
                        v.layout(l, t, r, b);
                        lastY=(int)event.getRawY();
                        desLastY=v.getTop()+20;
                        v.postInvalidate();
                        break;
                    case MotionEvent.ACTION_UP:
                        v_up_down.setBackgroundColor(Color.parseColor("#00FF00"));
                        lastY=(int)event.getRawY();
                        desLastY=v.getTop()+20;
                        // 离开屏幕的操作
                        break;
                    case (MotionEvent.ACTION_CANCEL):
                        // 手势撤消的操作
                        // 一般认为不能由用户主动触发。
                        // 系统在运行到一定程度下无法继续响应你的后续动作时会产生此事件
                        break;
                    default:
                        break;
                }
                // 这个返回值如果是false的话，那么它只会接受到第一个ACTION_DOWN的效果，
                // 后面的它认为没有触发，所以要想继续监听后续事件，需要返回值为true
                return true;
            }
        });
    }
    //手动校准-----------------------------------------------end
}